<template>
	<view class="upload-component">
		<slot v-if="$slots.default">
			<!-- 使用插槽自定义显示 -->
			<view @click="handleChooseFile">
				<slot></slot>
			</view>
		</slot>
		<template v-else>
			<view class="upload-box" @click="handleChooseFile" v-if="!previewUrl">
				<uni-icons type="upload" size="24" color="#999"></uni-icons>
				<text class="upload-text">{{ placeholder }}</text>
			</view>
			<view class="preview-box" v-else>
				<image :src="previewUrl" :style="{ width: size + 'rpx', height: size + 'rpx' }" mode="aspectFit"
					@click="previewImage"></image>
				<view class="action-buttons">
					<view class="action-btn replace" @click.stop="handleChooseFile">
						<uni-icons type="upload" size="16" color="#FFFFFF"></uni-icons>
					</view>
					<view class="action-btn delete" @click.stop="deleteFile">
						<uni-icons type="trash" size="16" color="#FFFFFF"></uni-icons>
					</view>
				</view>
			</view>
		</template>
	</view>
</template>

<script>
import env from '@/env.js';

export default {
	name: 'upload-file',
	props: {
		// 文件URL
		value: {
			type: String,
			default: ''
		},
		// 文件夹路径
		folderPath: {
			type: String,
			required: true
		},
		// 占位文本
		placeholder: {
			type: String,
			default: '点击上传文件'
		},
		// 组件大小
		size: {
			type: Number,
			default: 200
		},
		// 是否只允许图片
		imageOnly: {
			type: Boolean,
			default: true
		},
		// 文件大小限制（MB）
		maxSize: {
			type: Number,
			default: 5
		}
	},
	data() {
		return {
			previewUrl: this.value, // 预览URL（可以是远程URL或本地临时路径）
			tempFile: null, // 临时文件对象
			uploadProgress: 0
		}
	},
	watch: {
		value(newVal) {
			this.previewUrl = newVal;
		}
	},
	methods: {
		// 选择文件
		handleChooseFile() {
			uni.chooseImage({
				count: 1,
				sizeType: ['compressed'],
				sourceType: ['album', 'camera'],
				success: (res) => {
					if (res.tempFilePaths && res.tempFilePaths.length > 0) {
						// 检查文件大小
						const fileSize = res.tempFiles[0].size;
						if (fileSize > this.maxSize * 1024 * 1024) {
							uni.showToast({
								title: `文件大小不能超过${this.maxSize}MB`,
								icon: 'none'
							});
							return;
						}

						// 保存临时文件信息
						this.tempFile = {
							path: res.tempFilePaths[0],
							size: fileSize
						};

						// 设置预览URL
						this.previewUrl = res.tempFilePaths[0];

						// 触发事件
						this.$emit('change', {
							tempFile: this.tempFile,
							previewUrl: this.previewUrl
						});

						// 更新v-model
						this.$emit('input', this.previewUrl);

						console.log('选择的图片路径:', this.previewUrl);
					}
				},
				fail: (err) => {
					if (!err.errMsg.includes('cancel')) {
						uni.showToast({
							title: '选择文件失败',
							icon: 'none'
						});
					}
				}
			});
		},

		// 预览图片
		previewImage() {
			if (this.previewUrl) {
				uni.previewImage({
					urls: [this.previewUrl]
				});
			}
		},

		// 删除文件
		deleteFile() {
			this.previewUrl = '';
			this.tempFile = null;
			this.$emit('input', '');
			this.$emit('delete');
		},

		// 上传文件
		upload() {
			return new Promise((resolve, reject) => {
				// 如果没有临时文件且已有URL，说明是已上传的文件
				if (!this.tempFile) {
					resolve(this.previewUrl);
					return;
				}

				const token = uni.getStorageSync('Authorization');
				if (!token) {
					reject(new Error('未登录或token已过期'));
					return;
				}

				uni.showLoading({
					title: '上传中...',
					mask: true
				});

				// 使用env.js中的BASE_URL作为后端地址
				const uploadTask = uni.uploadFile({
					url: `${env.BASE_URL}/admin/common/upload`,
					filePath: this.tempFile.path,
					name: 'file',
					formData: {
						folderPath: this.folderPath.replace(/^\/+|\/+$/g, '')
					},
					header: {
						'Authorization': token
					},
					success: (uploadFileRes) => {
						uni.hideLoading();
						try {
							const res = JSON.parse(uploadFileRes.data);
							if (res.code === 1 || res.code === 200) {
								this.previewUrl = res.data;
								this.tempFile = null; // 上传成功后清除临时文件
								resolve(res.data);
							} else {
								reject(new Error(res.msg || '上传失败'));
							}
						} catch (e) {
							reject(new Error('解析响应数据失败'));
						}
					},
					fail: (err) => {
						uni.hideLoading();
						console.error('Upload failed:', err);
						reject(new Error(err.errMsg || '上传失败'));
					}
				});

				uploadTask.onProgressUpdate((res) => {
					this.uploadProgress = res.progress;
					this.$emit('progress', res.progress);
				});
			});
		}
	}
}
</script>

<style lang="scss">

.upload-component {
	display: inline-block;

	.upload-box {
		width: var(--size, 200rpx);
		height: var(--size, 200rpx);
		border: 2rpx dashed #DDDDDD;
		border-radius: 16rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		background-color: #F5F5F5;
		cursor: pointer;

		.upload-text {
			font-size: 24rpx;
			color: #999999;
			margin-top: 10rpx;
		}
	}

	.preview-box {
		position: relative;
		display: inline-block;

		image {
			border-radius: 16rpx;
			border: 2rpx solid #DDDDDD;
			width: var(--size, 200rpx);
			height: var(--size, 200rpx);
			object-fit: cover;
		}

		.action-buttons {
			position: absolute;
			top: 10rpx;
			right: 10rpx;
			display: flex;
			flex-direction: column;

			.action-btn {
				width: 40rpx;
				height: 40rpx;
				border-radius: 50%;
				display: flex;
				justify-content: center;
				align-items: center;
				margin-bottom: 10rpx;
				cursor: pointer;

				&.replace {
					background-color: #5E81F4;
				}

				&.delete {
					background-color: #FF5A5F;
				}
			}
		}
	}
}
</style>